#pragma once

#include <string>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cerrno>
#include "log.hpp"

// 声明外部变量
extern Log lg;

enum
{
    CREATR_ERROR = 1, 
    BIND_ERROR

};

static int backlog = 5;

class TcpServer
{
public:
    TcpServer(uint16_t port = 8080) : _port(port) {}

    void Init()
    {
        _ListenSockid = socket(AF_INET, SOCK_STREAM, 0);
        if (_ListenSockid < 0)
        {
            lg(Fatal, "socket create error, sockid:%d", _ListenSockid);
            exit(CREATR_ERROR);
        }
        lg(Info, "socket create success, sockid:%d", _ListenSockid);

        sockaddr_in local;
        uint32_t len = sizeof(local);
        bzero(&local, len);
        local.sin_family = AF_INET;
        local.sin_addr.s_addr = INADDR_ANY;
        local.sin_port = htons(_port);

        // 绑定
        if (bind(_ListenSockid, (const struct sockaddr *)&local, len) < 0)
        {
            lg(Fatal, "bind error, code:%d, message:%s", errno, strerror(errno));
            exit(BIND_ERROR);
        }
        lg(Info, "bind success");

        // 监听
        if (listen(_ListenSockid, backlog) < 0)
        {
            lg(Fatal, "listen error, code:%d, message:%s", errno, strerror(errno));
        }
        lg(Info, "listen success");
    }
    
    void Server(int sockid)
    {
        char buffer[1024];
        while(1)
        {
            bzero(buffer, sizeof(buffer));
            int n = read(sockid, buffer, sizeof(buffer));
            if (n > 0)
            {
                //buffer[n] = '0';//要么0，要么'\0'  你'0'什么意思？
                buffer[n] = '\0';

                std::string ret("Server response: ");
                ret += buffer;
                //没有 std::endl 不刷新缓冲区
                std::cout << "get message:" << buffer << std::endl;

                write(sockid, ret.c_str(), ret.size());
            }
            else 
            {
                break;
            }
        }
        close(sockid);
    }

    void Start()
    {
        sockaddr_in client;
        uint32_t len = sizeof(client);
        lg(Info, "tcpServer is running....");
        for (;;)
        {
            int sockid = accept(_ListenSockid, (struct sockaddr *)&client, &len);
            if (sockid < 0)
            {
                lg(Warning, "accept error");
                continue;
            }
            char IpBuf[16];
            //inet_ntop(AF_INET, &client, IpBuf, sizeof(IpBuf));
            inet_ntop(AF_INET, &client.sin_addr, IpBuf, sizeof(IpBuf));
            lg(Info, "success link...  %s:%d", IpBuf, ntohs(client.sin_port));
            
            //单进程版
            //Server(sockid);
            //close(sockid);
            
            //多进程版
            signal(SIGCHLD, SIG_IGN);
            pid_t pid = fork();
            if(pid == 0)
            {
                //子进程
                //像管道一样关闭文件
                close(_ListenSockid);
                //if(fork() > 0)  exit(0); //调用孙子进程
                Server(sockid);
                close(sockid);
                exit(0);
            }
            close(sockid);
            //waitpid(pid, nullptr, 0);


            //char buffer[1024];
            // while(1)
            // {
            //     bzero(buffer, sizeof(buffer));
            //     int n = read(sockid, buffer, sizeof(buffer));
            //     if (n > 0)
            //     {
            //         //buffer[n] = '0';//要么0，要么'\0'  你'0'什么意思？
            //         buffer[n] = '\0';

            //         std::string ret("Server response: ");
            //         ret += buffer;
            //         std::cout << "get message:" << buffer;

            //         write(sockid, ret.c_str(), ret.size());
            //     }
            //     else 
            //     {
            //         break;
            //     }
            // }
            //close(sockid);

            //要多次echo

            // char buffer[1024];
            // bzero(buffer, sizeof(buffer));
            // int n = read(sockid, buffer, sizeof(buffer));
            // if (n > 0)
            // {
            //     buffer[n] = '0';

            //     std::string Server("Server response: ");
            //     Server += buffer;
            //     std::cout << "get message:" << buffer <<std::endl;

            //     write(sockid, buffer, strlen(buffer));
            // }
            // else
            // {
            //     break;
            // }d

         
        }
        //close(sockid);
    }


private:
    int _ListenSockid = 0;
    std::string _ip = "0";
    uint16_t _port;
};